package com.icesoft.base.manager.service.security;

import com.icesoft.base.manager.entity.security.RelSysUserRole;
import com.icesoft.base.manager.helper.AuthUser;
import com.icesoft.base.manager.helper.SecurityUtils;
import com.icesoft.base.manager.security.suppose.IUserDetailsService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.Session;
import org.springframework.stereotype.Component;

@Component
@AllArgsConstructor
@Slf4j
public class AuthUserService {
    private static final String SPRING_SECURITY_CONTEXT_KEY = HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY;
    private final FindByIndexNameSessionRepository<? extends Session> sessionRepository;
    private final IUserDetailsService userDetailsService;
    private final RelSysUserRoleService relSysUserRoleService;

    public void reloadAuthority(int roleId) {
        relSysUserRoleService.findByRoleId(roleId).stream().map(RelSysUserRole::getUsername)
                .forEach(this::reloadAuthority);
    }

    public AuthUser reloadAuthority(String username) {
        AuthUser authUser = null;
        for (Session session : sessionRepository.findByPrincipalName(username).values()) {
            authUser = reloadUserAuthority(session);
        }
        return authUser;
    }

    /**
     * 重新加载用户权限
     */
    private AuthUser reloadUserAuthority(Session session) {
        SecurityContext securityContext = session.getAttribute(SPRING_SECURITY_CONTEXT_KEY);
        Authentication authentication = securityContext.getAuthentication();
        AuthUser authUser = SecurityUtils.getUser(authentication);
        if (authUser != null) {
            authUser = (AuthUser) userDetailsService.loadUserByUsername(authUser.getUsername());
            UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(
                    authUser, authentication.getCredentials(),
                    authUser.getAuthorities());
            result.setDetails(authentication.getDetails());
            securityContext.setAuthentication(result);
            session.setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext);
            ((FindByIndexNameSessionRepository<Session>) (sessionRepository)).save(session);
            log.info("用户：【{}】的权限更新成功，新权限：{}，访问范围：{}", authUser.getUsername(), authUser.getAuthorities(), authUser.getPermission().getOrgIds());
        }
        return authUser;
    }
}
